package com.example.demo.controller;


import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;
import com.example.demo.common.AjaxResult;
import com.example.demo.common.AppVariable;
import com.example.demo.common.PasswordUtils;
import com.example.demo.common.UserSessionUtils;
import com.example.demo.entity.Personalinfo;
import com.example.demo.entity.Userinfo;
import com.example.demo.entity.vo.UserinfoVO;
import com.example.demo.service.ArticleService;
import com.example.demo.service.CommentsService;
import com.example.demo.service.PersonalService;
import com.example.demo.service.UserService;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.JtaTransactionAnnotationParser;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.UUID;

import static java.time.LocalDateTime.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private ArticleService articleService;

    @Autowired
    private PersonalService personalService;

    @Autowired
    private CommentsService commentsService;



    @RequestMapping("/reg")
    public AjaxResult reg(Userinfo userinfo){
        //非空校验
        if (userinfo == null || !StringUtils.hasLength(userinfo.getUsername())||
        !StringUtils.hasLength(userinfo.getPassword())){
            return AjaxResult.fail(-1,"非法参数");
        }

        //取消重复名注册
        //根据用户名在数据库中查找有没有此信息
        Userinfo userinfo1 = userService.getUserByName(userinfo.getUsername());

        if(userinfo1 != null){
            return AjaxResult.fail(-1,"该用户名已被注册",1);
        }
        //密码加密
        userinfo.setPassword(PasswordUtils.encrypt(userinfo.getPassword()));
        //设置当前时间
        userinfo.setCreatetime(now());
        userinfo.setUpdatetime(now());

        userService.reg(userinfo);
        //注册的同时在person表中添加对应信息
        Userinfo userinfo2 = userService.getUserByName(userinfo.getUsername());
        userinfo.setId(userinfo2.getId());


        return AjaxResult.success(personalService.addPersonal(userinfo)); //将数据传给前端
    }

    //定义开始冻结时间
    private long startColdTime = 0;
    private  LineCaptcha lineCaptcha;//用于生成验证码
    @RequestMapping("/login")
    public AjaxResult login(HttpServletRequest request, String username, String password,String code){
        //非空校验
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password) || !StringUtils.hasLength(code)){
            return AjaxResult.fail(-1,"非法请求",null);
        }
        if (!code.equals(lineCaptcha.getCode())){
            return AjaxResult.fail(-1,"验证码错误",null);
        }
        //查询数据库
        Userinfo userinfo = userService.getUserByName(username);
        //先判断是否该锁定了
        //存储开始冻结时间
        if (userinfo.getState() == 4){
            //更新开始冻结时间
            startColdTime = System.currentTimeMillis();
            //创建一个进程，等待锁定时间后，将state改为1
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(10000);//当前进程休眠10s
                        //休眠10s后将state改为1
                        userService.updateStateToOne(userinfo.getId());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            userService.updateStateAdd(userinfo.getId());//将state字段+1,使下一次输入密码时状态为5
            return AjaxResult.success(0,"连续输错3次密码，用户已锁定,请"+AppVariable.CLOCK_TIME/1000+"s后重试",null);
        }
        //如果状态为5，返回锁定剩余时间
        if(userinfo.getState() == 5){
            long lastTime = (startColdTime + AppVariable.CLOCK_TIME - System.currentTimeMillis())/1000;
            return AjaxResult.success(0,"连续输错3次密码，用户已锁定,请"+lastTime+"s后重试",null);
        }

        if (userinfo!=null && userinfo.getId()>0){
            //有效用户
            //判断两个密码是否相等
            if (PasswordUtils.check(password,userinfo.getPassword())){
                //登录成功
                //将用户存储到session中
                HttpSession session = request.getSession();
                session.setAttribute(AppVariable.USER_SESSION_KEY,userinfo);
                userinfo.setPassword(""); // 返回前端之前隐藏敏感信息
                userService.updateStateToOne(userinfo.getId()); //用户登录成功，state置为1
                return AjaxResult.success(userinfo);
            }else{
                //密码错误，则将state+1，当state为4时，弹窗用户已锁定，请稍后再试，当发现state为4时，进入线程，并且返回剩余锁定时间
                //state+1
                userService.updateStateAdd(userinfo.getId());//将state字段+1
            }
        }
        return AjaxResult.success(0,"用户名或密码错误，请重试",null);

    }

    //获取验证码
    @RequestMapping("/getcode")
    public void getCode(HttpServletResponse response){
        // 随机生成 4 位验证码
        RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
        // 定义图片的显示大小
        lineCaptcha = CaptchaUtil.createLineCaptcha(100, 30);
        response.setContentType("image/jpeg");
        response.setHeader("Pragma", "No-cache");
        try {
            // 调用父类的 setGenerator() 方法，设置验证码的类型
            lineCaptcha.setGenerator(randomGenerator);
            // 输出到页面
            lineCaptcha.write(response.getOutputStream());

            // 关闭流
            response.getOutputStream().close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }



    @RequestMapping("/showinfo")
    public AjaxResult showInfo(HttpServletRequest request){
        UserinfoVO userinfoVO = new UserinfoVO();
        //1.得到当前登录用户(从session中获取)
        Userinfo userinfo = UserSessionUtils.getSessionUser(request);
        if (userinfo==null){
            return AjaxResult.fail(-1,"非法请求");
        }
        //Spring 提供深克隆方式
        BeanUtils.copyProperties(userinfo,userinfoVO);
        //2.得到用户发表文章的总数
        userinfoVO.setArtCount(articleService.getArtCountByUid(userinfo.getId()));
        //设置用户的github地址
        Personalinfo personalinfo = personalService.showPersonalInfo(userinfo.getId());
        if (personalinfo!=null){
            userinfoVO.setGithub(personalinfo.getGithub());
        }

        return AjaxResult.success(userinfoVO);

    }


    //根据 id 查用户信息
    @RequestMapping("/getuserbyid")
    public AjaxResult getUserById(Integer id){
        //非空校验
        if (id == null || id <=0){
            return AjaxResult.fail(-1,"非法参数");
        }

        Userinfo userinfo = userService.gerUserById(id);
        if (userinfo == null || userinfo.getId() <= 0){
            //无效参数
            return AjaxResult.fail(-1,"非法参数");
        }

        // 去除敏感信息
        userinfo.setPassword("");
        //查询用户发表了多少文章
        UserinfoVO userinfoVO = new UserinfoVO();
        BeanUtils.copyProperties(userinfo,userinfoVO); // 将userinfo 放到userinfoVO
        //查询当前用户发表的文章
        userinfoVO.setArtCount(articleService.getArtCountByUid(id));
        //设置用户的github地址
        Personalinfo personalinfo = personalService.showPersonalInfo(id);
        if (personalinfo!=null){
            userinfoVO.setGithub(personalinfo.getGithub());
        }
        return AjaxResult.success(userinfoVO);


    }


    //草稿左侧个人信息
    @RequestMapping("/showdraftinfo")
    public AjaxResult showDraftInfo(HttpServletRequest request){

        UserinfoVO userinfoVO = new UserinfoVO();
        //1.得到当前登录用户(从session中获取)
        Userinfo userinfo = UserSessionUtils.getSessionUser(request);
        if (userinfo==null){
            return AjaxResult.fail(-1,"非法请求");
        }
        //Spring 提供深克隆方式
        BeanUtils.copyProperties(userinfo,userinfoVO);
        //2.得到用户发表文章的总数
        userinfoVO.setArtCount(articleService.getDraftCountByUid(userinfo.getId()));
        //设置作者的github地址
        Personalinfo personalinfo = personalService.showPersonalInfo(userinfo.getId());
        if (personalinfo!=null){
            userinfoVO.setGithub(personalinfo.getGithub());
        }
        return AjaxResult.success(userinfoVO);

    }

    //根据用户id返回用户名
    @RequestMapping("/getusernamebyuid")
    public AjaxResult getUsernameById(Integer uid){

        Userinfo userinfo = userService.getUserById(uid);
        return AjaxResult.success(200,userinfo.getUsername(),1);
    }

    //根据replaycomments表中的rid获取uid，然后根据uid查找用户名
    @RequestMapping("/getusernamebyrid")
    public AjaxResult getusernamebyrid(Integer rid){
        if (rid==null||rid<=0){
            return AjaxResult.fail(-1);
        }
        int uid = userService.getUidByRid(rid);

        return getUsernameById(uid);
    }


    //上传头像
    @RequestMapping("/subphoto")
    public AjaxResult updataPhoto(HttpServletRequest request,
                                  @RequestParam("file") MultipartFile file){
        //非空校验
        if (file == null){
            return AjaxResult.fail(-1,"图片错误");
        }
        //要上传的文件名称
        String originalFileName = file.getOriginalFilename();

        //获取当前登录用户信息
        Userinfo userinfo = UserSessionUtils.getSessionUser(request);
        if (userinfo == null || userinfo.getId() <= 0){
            //无效参数
            return AjaxResult.fail(-1,"非法参数");
        }

        //获取文件后缀
        String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));
        //生成图片随机名称
        String photoName = UUID.randomUUID().toString()+suffix;

        //生成图片的绝对路径，存到数据库中
        String photoPathAb = AppVariable.IMG_PATH_ABSOLUTE + photoName;
        //生成图片的相对路径，返回浏览器
        String photoPathRe = AppVariable.IMG_PATH_RELATIVE + photoName;

        System.out.println("绝对路径"+photoPathAb);
        System.out.println("相对路径"+photoPathRe);

        //根据绝对路径生成文件
        File saveFile = new File(photoPathAb);

        try {
            //将要上传的文件绝对路基保存到服务器文件系统
            file.transferTo(saveFile);
            //保存图片的相对路径到数据库中
            userService.updatePhotoById(userinfo.getId(),photoPathRe);
            //还要将评论表，评论回复表中的头像字段改成相应的路径
            commentsService.updateCommentsPhoto(userinfo.getId(),photoPathRe);
            commentsService.updateCReplayommentsPhoto(userinfo.getId(),photoPathRe);

            //修改保存的session信息
            userinfo.setPhoto(photoPathRe);
            HttpSession session = request.getSession(false);
            session.setAttribute(AppVariable.USER_SESSION_KEY,userinfo);



        } catch (IOException e) {
            e.printStackTrace();
        }


        return AjaxResult.success(photoPathRe);



    }




}




















